package ch.ethz.fcl.metrobuzz.data.accessibility.activity;

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;

import ch.ethz.fcl.metrobuzz.data.transit.Stop;
import ch.ethz.fcl.metrobuzz.spatialindex.object2d.Point2D;
import ch.ethz.fcl.metrobuzz.tools.MBTools;

public class PointOfInterest {
	private float x, y; // location of x & y
	// record 5 nearby stops and its walk cost
	private Queue<Stop> nearbyStops;
	private int nearbyStopSize = 10;
	private int elementsLeft = nearbyStopSize;
	private StopDistanceComparator comparator;

	private Map<Stop, Float> stopWalkCostMap = null;

	public PointOfInterest() {
		this.comparator = new StopDistanceComparator();
		nearbyStops = new PriorityQueue<Stop>(nearbyStopSize, comparator);
		stopWalkCostMap = new HashMap<Stop, Float>();
	}

	public void setPosition(float x, float y) {
		this.x = x;
		this.y = y;
	}

	public float getX() {
		return x;
	}

	public float getY() {
		return y;
	}

	public void addNearbyStop(Stop stop) {
		if (elementsLeft > 0) {
			nearbyStops.add(stop);
			elementsLeft--;
		} else {
			// there is already 1 or more elements => compare to the least
			int compared = comparator.compare(stop, nearbyStops.element());
			if (compared == 1) {
				nearbyStops.remove();
				nearbyStops.add(stop);
			}
		}
		// MBTools.debug("Nearby stops size " + nearbyStops.size(), false);
	}

	public Queue<Stop> getNearbyStops() {
		return nearbyStops;
	}

	public Point2D toPoint() {
		return new Point2D(x, y);
	}

	public void addStopWalkCost(Stop stop, float cost) {
		stopWalkCostMap.put(stop, cost);
	}

	public float getStopWalkCost(Stop stop) {
		return stopWalkCostMap.get(stop);
	}

	private class StopDistanceComparator implements Comparator<Stop> {
		@Override
		public int compare(Stop s1, Stop s2) {
			if (MBTools.distance(x, y, s1.getX(), s1.getY()) < MBTools
					.distance(x, y, s2.getX(), s2.getY()))
				return 1;

			else if (MBTools.distance(x, y, s1.getX(), s1.getY()) > MBTools
					.distance(x, y, s2.getX(), s2.getY()))
				return -1;

			return 0;
		}
	}
}
